﻿using DAL;
using RTS.Lib.Comm.ADSBLL;
using RTS.Lib.Comm.OPCBLL;
using RTS.Lib.Comm.OPCModel;
using RTS.Lib.Comm.S7BLL;
using RTS.Lib.Log;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;


namespace ControlTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            LogQueue.Run();
            LogQueue.AddLog(new LogEventArgs(LogLevel.Info, "软件", $"启动", ""), false, true, true);

            try
            {
                Initial();
            }
            catch (Exception ex)
            {
                LogQueue.AddLog(new LogEventArgs(LogLevel.Error, "Comm", $"{ex.Message}", "", ex), true, true, true);
            }
        }
        #region OPC
        private XmlDocument xd { get; set; } = new XmlDocument();

        public Server MyServer { get; set; }
        public Group MyGroup { get; set; }
        public static MSSQLHelper AMSSQL { get; set; }
        private DataTableCollection TreeviewNodeDataTableCollection { get; set; }
        private Dictionary<string, bool> IsDataTableUpdate { get; set; }
        private void Initial()
        {
            try
            {
                string TagConfigurationMode = GetAppconfigInfo.getAppSettingsValue("TagConfigurationMode");
                MyServer = new Server();
                MyServer.TagConfigurationMode = TagConfigurationMode;
                switch (TagConfigurationMode)
                {
                    case "MSSQLS7":
                        AMSSQL = new MSSQLHelper(GetAppconfigInfo.GetConnectionStrings("AMSConStr"));
                        MyServer.S7Devicedt = AMSSQL.GetDataTable(GetAppconfigInfo.getAppSettingsValue("DeviceSelectSQL"));
                        MyServer.S7Tagdt = AMSSQL.GetDataTable(GetAppconfigInfo.getAppSettingsValue("TagSelectSQL"));
                        break;
                    case "XML1":
                    case "XML2":
                        MyServer.XMLPath = GetAppconfigInfo.getAppSettingsValue("DefaultTagsPath");
                        break;
                    default:
                        throw new Exception($"变量配置模式“{TagConfigurationMode}”不存在");
                }
                MyServer.Initial();
                TreeviewNodeDataTableCollection = InitailDataTableCollection();
                InitialTreeView();
                InitailGroup();

                System.Timers.Timer TimerHeartBeat = new System.Timers.Timer(1000);
                TimerHeartBeat.Elapsed += new System.Timers.ElapsedEventHandler(timerHeartBeat_Tick);  //到达时间的时候执行倒计时事件timeout；
                TimerHeartBeat.AutoReset = true;
                TimerHeartBeat.Start();

            }
            catch (Exception ex)
            {
                LogQueue.AddLog(new LogEventArgs(LogLevel.Error, "Comm", $"Initial中出现异常，异常信息：{ex.Message}", "", ex), true, true, true);
            }
        }
        short currentValue = 0;
        private void timerHeartBeat_Tick(object sender, EventArgs e)
        {
            try
            {
                #region 读一下request的值，如果为0了，则把feedback也写回0
                ItemValueResult[] result = null;
                string[] itemNames = new string[] { "PLCS.PLC1.ControlTest.Plc_iRequest" };
                result = MyGroup.Read(itemNames);
                string Plc_iRequest = result[0].Value.ToString();
                if (Convert.ToInt16(Plc_iRequest) == 0)
                {
                    Item item2 = MyGroup.GetItembyName("PLCS.PLC1.ControlTest.Mes_iFeedback");
                    ItemValue itemValue2 = new ItemValue(item2);
                    itemValue2.Value = CovertToDotNet(itemValue2, "0");
                    ItemResult[] itemResults2 = MyGroup.Write(new ItemValue[] { itemValue2 });
                }
                #endregion


                currentValue++;
                //获取选中的Item
                Item item = MyGroup.GetItembyName("PLCS.PLC1.ControlTest.Mes_iHeartBeat");
                ItemValue itemValue = new ItemValue(item);
                itemValue.Value = CovertToDotNet(itemValue, currentValue.ToString());
                ItemResult[] itemResults1 = MyGroup.Write(new ItemValue[] { itemValue });
            }
            catch (Exception ex)
            {
                LogQueue.AddLog(new LogEventArgs(LogLevel.Error, "AMS Core", $"timerHeartBeat_Tick() catch exception,{ex.Message}", "ErrorCode", ex), true, true, true);
            }
        }
        private object CovertToDotNet(Item item, string value)
        {
            object result = null;
            DriveType driveType = item.DriveType;
            switch (driveType)
            {
                case DriveType.S7:
                    {
                        RTS.Lib.Comm.S7Model.DataType datatype = ((RTSS7Tag)item.ActualTag).DataType;
                        switch (datatype)
                        {
                            case RTS.Lib.Comm.S7Model.DataType.Bool:
                                if (value == "1")
                                    result = true;
                                else if (value == "0")
                                    result = false;
                                else
                                    result = Convert.ToBoolean(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.Byte:
                                result = Convert.ToByte(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.SInt:
                            case RTS.Lib.Comm.S7Model.DataType.Int:
                                result = Convert.ToInt16(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.DInt:
                                result = Convert.ToInt32(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.Word:
                                result = Convert.ToUInt16(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.DWord:
                                result = Convert.ToUInt32(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.Real:
                                result = Convert.ToSingle(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.String:
                            case RTS.Lib.Comm.S7Model.DataType.Array_Of_Char:
                                result = value.ToString();
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.Date:
                                result = Convert.ToDateTime(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.Time:
                                result = Convert.ToInt32(value);
                                break;
                            case RTS.Lib.Comm.S7Model.DataType.Time_Of_Day:
                                result = Convert.ToDateTime(value);
                                break;
                            default:
                                throw new Exception($"CovertToDotNet中变量类型“{datatype}”不存在"); ;
                        }
                    }

                    break;


            }
            return result;
        }
        private void InitailGroup()
        {
            MyGroup = MyServer.CreateGroup("AllTag");
            MyGroup.AddItems(MyServer.GetAllItems());
            MyGroup.DataChanged += Group_DataChanged;
            MyGroup.InitialDataChange(10);
        }
        /// <summary>
        /// Group的datachange事件，更改对应dt，如果listview显示的是当前dt，就把listview也更新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Group_DataChanged(object sender, ItemValueResultEventArgs e)
        {
            //LogQueue.AddLog(new LogEventArgs(LogLevel.Info, "Comm", $"DC累计次数{a}", ""), true, true, true);

            IsDataTableUpdate = InitialDataTableUpdateStatus();
            ItemValueResult[] ItemValueResults = e.ItemValueResults;
            foreach (var item in ItemValueResults)
            {
                string itemName = item.ItemName;
                //string treeviewNodeName = GetItemTreeViewNodeName(itemName);
                //DataTable currentdt = TreeviewNodeDataTableCollection[treeviewNodeName];
                //IsDataTableUpdate[treeviewNodeName] = true;
                //int length = currentdt.Rows.Count;
                //for (int i = 0; i < length; i++)
                //{
                //    if (currentdt.Rows[i]["TagName"].ToString() == item.ItemName)
                //    {
                //        currentdt.Rows[i]["Value"] = item.Value == null ? "" : item.Value.ToString();
                //        currentdt.Rows[i]["UpdateTime"] = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff");
                //        currentdt.Rows[i]["Status"] = item.ErrorInfo == string.Empty ? "Status OK" : item.ErrorInfo;
                //        break;
                //    }
                //}
                if (itemName == "PLCS.PLC1.ControlTest.Plc_sCarrierId")
                {
                   // LogQueue.AddLog(new LogEventArgs(LogLevel.Info, "DataChanged", $"收到{item.ItemName}=[{item.Value.ToString()}]", ""), false, true, true);

                    if (item == null)
                        return;
                    this.BeginInvoke((new Action(() =>
                    {
                        textBox1.Text = item.Value.ToString();
                    })));

                }
                if (itemName == "PLCS.PLC1.ControlTest.Plc_iRequest")
                {
                    LogQueue.AddLog(new LogEventArgs(LogLevel.Info, "DataChanged", $"收到Plc_iRequest=[{item.Value.ToString()}]", ""), false, true, true);
                    if (item == null)
                        return;
                    try
                    {
                        if (Convert.ToInt16(item.Value.ToString()) == 11)
                        {
                            ItemValueResult[] result = null;
                            string[] itemNames = new string[] { "PLCS.PLC1.ControlTest.Plc_sCarrierId" };
                            result = MyGroup.Read(itemNames);
                            string cid = result[0].Value.ToString();
                            this.BeginInvoke((new Action(() =>
                            {
                                CheckCarrier(cid);
                            })));
                        }
                        else if (Convert.ToInt16(item.Value.ToString()) == 0)
                        {
                            Item item2 = MyGroup.GetItembyName("PLCS.PLC1.ControlTest.Mes_iFeedback");
                            ItemValue itemValue2 = new ItemValue(item2);
                            itemValue2.Value = CovertToDotNet(itemValue2, "0");
                            ItemResult[] itemResults1 = MyGroup.Write(new ItemValue[] { itemValue2 });
                            LogQueue.AddLog(new LogEventArgs(LogLevel.Info, "DataChanged", $"Plc_iRequest=0,PLC请求复位,将Mes_iFeedback的值写为0", ""), false, true, true);

                        }
                        else
                        {
                            LogQueue.AddLog(new LogEventArgs(LogLevel.Warn, "DataChanged", $"Plc_iRequest={item.Value.ToString()},异常数值", ""), false, true, true);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogQueue.AddLog(new LogEventArgs(LogLevel.Error, "DataChanged", $"处理Plc_iRequest时，发生异常，{ex.Message}", "ErrorCode", ex), false, true, true);
                    }
                }
            }
            if (listView1.Tag == null)
                return;
            string currentListView = listView1.Tag.ToString();
            if (IsDataTableUpdate.ContainsKey(currentListView) && IsDataTableUpdate[currentListView] == true)
            {
                //Action<int> action = (data) =>
                //{
                //    DataTableToListView(listView1, AllDeviceTagDataTableCollection[currentListView]);
                //};
                //Invoke(action);
                this.Invoke(new Action(() =>
                {
                    UpdateListView(listView1, TreeviewNodeDataTableCollection[currentListView]);
                }));

            }
        }
        /// <summary>
        /// 用于记录每次dc中每个dt是否更新了数据
        /// </summary>
        /// <returns></returns>
        private Dictionary<string, bool> InitialDataTableUpdateStatus()
        {
            Dictionary<string, bool> result = new Dictionary<string, bool>();
            foreach (DataTable item in TreeviewNodeDataTableCollection)
            {
                result.Add(item.TableName, false);
            }
            return result;
        }

        /// <summary>
        /// 初始化Treeview各个组的变量dt,放到DataTableCollection中，供datachange修改值用
        /// </summary>
        private DataTableCollection InitailDataTableCollection()
        {
            DataSet AllDataSet = new DataSet();
            DataTableCollection AllDataTables = AllDataSet.Tables;
            Item[] items = MyServer.GetAllItems();
            foreach (Item item in items)
            {
                string treeviewNodeName = GetItemTreeViewNodeName(item.ItemName);
                if (!AllDataTables.Contains(treeviewNodeName))
                {
                    DataTable treeviewNodedt = ConfigDataTableStructure(treeviewNodeName);
                    AllDataTables.Add(treeviewNodedt);
                }
            }
            return AllDataTables;
        }
        #region 变量所属treeview组相关
        /// <summary>
        /// 获取变量在treeview中的组名
        /// </summary>
        /// <param name="itemName"></param>
        /// <returns></returns>
        private string GetItemTreeViewNodeName(string itemName)
        {
            string result = string.Empty;
            int dotCount = CharCount(itemName, '.');
            if (dotCount == 2)//点直接属于设备下
            {
                int index = NthIndexOf(itemName, '.', 2);
                result = itemName.Substring(0, index);
            }
            else if (dotCount > 2)//点属于tagGroup
            {
                int index = NthIndexOf(itemName, '.', 3);
                result = itemName.Substring(0, index);
            }
            return result;
        }
        /// <summary>
        /// 找到字符在字符串中第n次出现的位置
        /// </summary>
        /// <param name="targetString"></param>
        /// <param name="targetChar"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        private int NthIndexOf(string targetString, char targetChar, int n)
        {
            int result = -1;
            if (n < 1)
            {
                result = -1;
                return result;
            }
            for (int i = 0; i < n; i++)
            {
                result = targetString.IndexOf(targetChar, result + 1);
                if (result == -1)
                {
                    return result;
                }
            }
            return result;
        }
        /// <summary>
        /// 计算searchChar在searchString中出现的次数
        /// </summary>
        /// <param name="targetString"></param>
        /// <param name="targetChar"></param>
        /// <returns></returns>
        private int CharCount(string targetString, char targetChar)
        {
            int result = 0;
            int length = targetString.Length;
            for (int i = 0; i < length; i++)
            {
                if (targetString[i] == targetChar)
                {
                    result++;
                }
            }
            return result;
        }
        #endregion
        /// <summary>
        /// 配置listview需要显示的dt的结构
        /// </summary>
        /// <param name="deviceName"></param>
        /// <returns></returns>
        private DataTable ConfigDataTableStructure(string treeviewNodeName)
        {
            DataTable result = new DataTable(treeviewNodeName);
            result.Columns.Add("TagName", Type.GetType("System.String"));
            result.Columns.Add("Type", Type.GetType("System.String"));
            result.Columns.Add("Value", Type.GetType("System.String"));
            result.Columns.Add("UpdateTime", Type.GetType("System.String"));
            result.Columns.Add("Status", Type.GetType("System.String"));
            result.Columns.Add("Address", Type.GetType("System.String"));

            result.PrimaryKey = new DataColumn[] { result.Columns["TagName"] };

            foreach (Item item in MyServer.GetAllItems())
            {
                string itemTreeviewNodeName = GetItemTreeViewNodeName(item.ItemName);
                if (itemTreeviewNodeName == treeviewNodeName)
                {
                    DataRow dr = result.NewRow();
                    dr["TagName"] = item.ItemName;
                    dr["Type"] = GetItemDataType(item);
                    dr["Address"] = GetItemAddress(item);
                    result.Rows.Add(dr);
                }
            }

            return result;
        }
        /// <summary>
        /// 获取item中各自驱动类型中的数据类型
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private string GetItemDataType(Item item)
        {
            string result = string.Empty;
            DriveType driveType = item.DriveType;
            switch (driveType)
            {
                case DriveType.S7:
                    {
                        RTS.Lib.Comm.S7BLL.RTSS7Tag tag = (RTS.Lib.Comm.S7BLL.RTSS7Tag)item.ActualTag;
                        RTS.Lib.Comm.S7Model.DataType dataType = tag.DataType;
                        result = dataType.ToString();
                    }
                    break;

                default:
                    throw new Exception($"GetItemDataType中驱动类型“{driveType}”不存在");
            }
            return result;
        }
        private string GetItemAddress(Item item)
        {
            string result = string.Empty;
            DriveType driveType = item.DriveType;
            switch (driveType)
            {
                case DriveType.S7:
                    {
                        RTS.Lib.Comm.S7BLL.RTSS7Tag tag = (RTS.Lib.Comm.S7BLL.RTSS7Tag)item.ActualTag;
                        RTS.Lib.Comm.S7Model.DataType dataType = tag.DataType;
                        if (dataType == RTS.Lib.Comm.S7Model.DataType.Bool)
                        {
                            int start = tag.MyS7Tag.Start / 8;
                            int dd = tag.MyS7Tag.Start % 8;
                            result = $"[{tag.MyS7Tag.DBNumber}] {start}.{dd}";
                        }
                        else
                        {
                            result = $"[{tag.MyS7Tag.DBNumber}] {tag.MyS7Tag.Start}";
                        }
                    }
                    break;

                default:
                    throw new Exception($"GetItemDataType中驱动类型“{driveType}”不存在");
            }
            return result;
        }
        /// <summary>
        /// 初始化左侧设备treeview
        /// </summary>
        private void InitialTreeView()
        {
            treeView1.BeginUpdate();
            treeView1.Nodes.Clear();
            //XmlNode projectName = xd.SelectSingleNode($"/project/name");
            //TreeNode root = treeView1.Nodes.Add(projectName.InnerText);
            TreeNode root = treeView1.Nodes.Add("Project");

            foreach (DataTable TreeviewNodeDataTable in TreeviewNodeDataTableCollection)
            {
                root.Nodes.Add(TreeviewNodeDataTable.TableName);
            }
            treeView1.EndUpdate();
            treeView1.ExpandAll();
        }
        /// <summary>
        /// 获取一个驱动下的所有设备
        /// </summary>
        /// <param name="channelNode"></param>
        /// <returns></returns>
        private XmlNodeList GetDevicesNode()
        {
            XmlNodeList result;
            result = xd.SelectNodes($"//devices/device");
            return result;
        }

        #region 事件--------------
        /// <summary>
        /// treeview选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                LoadListViewData(e.Node);
            }
        }
        //@A正式使用的时候还是让客户选择文件位置
        private void ToolStripMenuItem_openTagFile_Click(object sender, EventArgs e)
        {
            //openFileDialog_tagFile.Filter = "XML文件|*.XML";
            //if (openFileDialog_tagFile.ShowDialog() == DialogResult.OK)
            //{
            //    string manualTagsPath = openFileDialog_tagFile.FileName;
            //    Initial(manualTagsPath);
            //}
        }
        /// <summary>
        /// listview右键菜单，当有选中行的时候显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

        }
        /// <summary>
        /// 写入选中行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToolStripMenuItem_writeValue_Click(object sender, EventArgs e)
        {

            //获取选中的Item
            string itemName = listView1.SelectedItems[0].SubItems[0].Text;
            Item item = MyGroup.GetItembyName(itemName);

            Frm_WriteValue frm_WriteValue = new Frm_WriteValue(MyGroup, item);
            frm_WriteValue.ShowDialog();
        }
        /// <summary>
        /// 点击listview列头按照此列排序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            ListViewSorter sorter = listView1.ListViewItemSorter as ListViewSorter;
            if (sorter != null)
            {
                sorter.SorIndex = e.Column;
                //升序、降序变换
                if (sorter.SortType == SortOrder.Descending)
                {
                    sorter.SortType = SortOrder.Ascending;
                }
                else if (sorter.SortType == SortOrder.Ascending)
                {
                    sorter.SortType = SortOrder.Descending;
                }
                //列表视图的项进行排序
                listView1.Sort();
            }
        }
        #endregion 事件
        /// <summary>
        /// 点击treeview时更新listview
        /// </summary>
        /// <param name="treeNode"></param>
        private void LoadListViewData(TreeNode treeNode)
        {
            int level = treeNode.Level;

            //listView1.Clear();
            listView1.Tag = string.Empty;

            string deviceName;
            switch (level)
            {
                case 1://device
                    deviceName = treeNode.Text;
                    DataTable currentDevicedt = TreeviewNodeDataTableCollection[deviceName];
                    DataTableToListView(listView1, currentDevicedt);
                    listView1.Tag = deviceName;
                    break;
                default:
                    break;
            }

        }
        /// <summary>
        /// DataTable转ListView
        /// </summary>
        /// <param name="lv"></param>
        /// <param name="dt"></param>
        public void DataTableToListView(ListView lv, DataTable dt)
        {
            try
            {
                if (dt != null)
                {
                    //this.Invoke(new Action(() =>

                    //{
                    //lv.View = View.Details;
                    //lv.FullRowSelect = true;
                    lv.BeginUpdate();
                    lv.Clear();
                    lv.View = View.Details;
                    //lv.AllowColumnReorder = true;
                    //lv.GridLines = true;
                    //lv.Items.Clear();
                    //lv.Columns.Clear();
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        lv.Columns.Add(dt.Columns[i].Caption.ToString(), dt.Columns[i].Caption.Trim().Length * 20, HorizontalAlignment.Left);
                    }
                    foreach (DataRow dr in dt.Rows)
                    {
                        ListViewItem lvi = new ListViewItem(dr[0].ToString());
                        for (int j = 1; j < dt.Columns.Count; j++)
                        {
                            lvi.SubItems.Add(dr[j].ToString());
                        }
                        lv.Items.Add(lvi);
                    }
                    lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
                    lv.EndUpdate();
                    //}));

                    foreach (ColumnHeader item in listView1.Columns)//让listview宽度自适应，-1根据列内容自适应，-2根据列标题自适应
                    {
                        item.Width = -1;
                    }
                }
                else
                {
                    LogQueue.AddLog(new LogEventArgs(LogLevel.Warn, "Comm", $"当前dt为null", ""), true, true, true);
                }
            }
            catch (Exception ex)
            {
                LogQueue.AddLog(new LogEventArgs(LogLevel.Error, "Comm", $"DataTable转ListView出现异常，异常信息：{ex.Message}", "", ex), true, true, true);
            }
        }
        public void UpdateListView(ListView lv, DataTable dt)
        {
            try
            {
                int length = dt.Rows.Count;
                //lv.Items[0].SubItems[2].Text = dt.Rows[0][2].ToString();
                //lv.Items[0].SubItems[3].Text = dt.Rows[0][3].ToString();
                //lv.Items[0].SubItems[4].Text = dt.Rows[0][4].ToString();

                for (int i = 0; i < length; i++)//dt的行索引
                {
                    for (int j = 0; j < length; j++)//listitem的行索引
                    {
                        if (dt.Rows[i]["TagName"].ToString() == lv.Items[j].SubItems[0].Text)
                        {
                            lv.Items[j].SubItems[2].Text = dt.Rows[i][2].ToString();
                            lv.Items[j].SubItems[3].Text = dt.Rows[i][3].ToString();
                            lv.Items[j].SubItems[4].Text = dt.Rows[i][4].ToString();
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogQueue.AddLog(new LogEventArgs(LogLevel.Error, "Comm", $"UpdateListView出现异常，异常信息：{ex.Message}", "", ex), true, true, true);
            }
        }
        #endregion
        private void button1_Click(object sender, EventArgs e)
        {
            CheckCarrier(this.textBox1.Text);
        }
        public void CheckCarrier(string cid)
        {
            int val;
            TrayCheckControl.ErrorCodeSocket ec = this.trayCheckControl.CheckTray(cid, out val);
            this.label2.Text = ec.ToString();
            int iFeedback = 13;
            int count = 0;
            if (TrayCheckControl.ErrorCodeSocket.Success == ec)
            {
                LogQueue.AddLog(new LogEventArgs(LogLevel.Info, "托盘查询", $"[{cid}]查询成功,剩余次数[{val}]", ""), false, true, true);
                iFeedback = 12;
                count = val;
                this.label1.Text = val.ToString();
            }
            else
                LogQueue.AddLog(new LogEventArgs(LogLevel.Warn, "托盘查询", $"[{cid}]查询失败,{ec.ToString()}", ""), false, true, true);

            try
            {
                Thread t = new Thread(delegate () { WriteValueBackToPLC(iFeedback, count); });
                t.IsBackground = true;
                t.Start();
            }
            catch (Exception ex)
            {

            }
        }
        private void WriteValueBackToPLC(int iFeedback, int count)
        {
            System.Threading.Thread.Sleep(100);

            Item item1 = MyGroup.GetItembyName("PLCS.PLC1.ControlTest.Mes_iRemainedValue");
            ItemValue itemValue1 = new ItemValue(item1);
            itemValue1.Value = CovertToDotNet(itemValue1, count.ToString());


            Item item2 = MyGroup.GetItembyName("PLCS.PLC1.ControlTest.Mes_iFeedback");
            ItemValue itemValue2 = new ItemValue(item2);
            itemValue2.Value = CovertToDotNet(itemValue2, iFeedback.ToString());
            try
            {
                ItemResult[] itemResults1 = MyGroup.Write(new ItemValue[] { itemValue1, itemValue2 });
                LogQueue.AddLog(new LogEventArgs(LogLevel.Info, "写操作", $"向PLC写回查询值,剩余次数=[{itemValue1.Value.ToString()}],请求值=[{itemValue2.Value.ToString()}]", ""), false, true, true);

            }
            catch (Exception ex)
            {
                LogQueue.AddLog(new LogEventArgs(LogLevel.Error, "写操作", $"发生异常，{ex.Message}", "", ex), false, true, true);
            }
        }
        private void Form_Load(object sender, EventArgs e)
        {
            this.trayCheckControl.Init();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("软件退出后，100站将无法实现托盘使用次数查询功能", "请确认要退出该软件吗？", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
            {
                //System.Environment.Exit(0);
            }
            else
                e.Cancel = true;
        }
    }
    public class DoubleBufferListView : ListView
    {
        public DoubleBufferListView()
        {
            SetStyle(ControlStyles.DoubleBuffer |
              ControlStyles.OptimizedDoubleBuffer |
              ControlStyles.AllPaintingInWmPaint, true);
            UpdateStyles();
        }
    }
    public class ListViewSorter : IComparer
    {
        //当前排序列的下标
        private int _sorIndex;

        public int SorIndex
        {
            get { return _sorIndex; }
            set { _sorIndex = value; }
        }
        private SortOrder _SortType = SortOrder.Ascending;
        //排序方式
        public SortOrder SortType
        {
            get { return _SortType; }
            set { _SortType = value; }
        }
        //用于比较的类
        private CaseInsensitiveComparer ObjectCompare = new CaseInsensitiveComparer();

        public int Compare(object x, object y)
        {
            int result = 0;
            ListViewItem a = (ListViewItem)x;
            ListViewItem b = (ListViewItem)y;
            //数字列，修复数字列排序不对的问题
            //if (System.Text.RegularExpressions.Regex.IsMatch(a.SubItems[SorIndex].Text, @"^\d+(\.\d+)?$"))
            //    result = ObjectCompare.Compare(Convert.ToDecimal(a.SubItems[SorIndex].Text), Convert.ToDecimal(b.SubItems[SorIndex].Text));
            //else
            result = ObjectCompare.Compare(a.SubItems[SorIndex].Text, b.SubItems[SorIndex].Text);
            if (_SortType == SortOrder.Descending)
                return -result;
            else if (_SortType == SortOrder.Ascending)
                return result;
            else
                return 0;

        }
    }
}
